/**
 * @file debugger.h
 * @brief VimL虚拟机调试器
 * @author VimLVM Team
 * @date 2025
 */

#ifndef VIML_DEBUGGER_H
#define VIML_DEBUGGER_H

#include "common.h"
#include "debug_info.h"
#include "vm.h"
#include <memory>
#include <unordered_map>
#include <vector>

namespace viml {

// 调试器事件类型
enum class DebugEvent {
    BREAKPOINT_HIT,
    STEP,
    ERROR,
    HALT
};

// 调试事件回调
class DebugEventHandler {
public:
    virtual ~DebugEventHandler() = default;
    virtual void on_event(DebugEvent event, size_t line, const std::string& message = "") = 0;
};

// 调试器类
class Debugger {
public:
    Debugger(VM& vm);
    ~Debugger() = default;
    
    // 调试控制
    void start_debugging();
    void stop_debugging();
    
    // 断点管理
    void add_breakpoint(const std::string& filename, size_t line);
    void remove_breakpoint(const std::string& filename, size_t line);
    void clear_breakpoints();
    std::vector<std::pair<std::string, size_t>> list_breakpoints() const;
    
    // 单步执行
    void step_into();
    void step_over();
    void step_out();
    void continue_execution();
    
    // 变量查看
    Value get_variable(const std::string& name) const;
    std::unordered_map<std::string, Value> get_local_variables() const;
    std::unordered_map<std::string, Value> get_global_variables() const;
    
    // 调用栈信息
    std::vector<VM::StackFrame> get_call_stack() const;
    
    // 当前执行位置
    size_t get_current_line() const;
    std::string get_current_function() const;
    std::string get_current_file() const;
    
    // 事件处理
    void set_event_handler(std::unique_ptr<DebugEventHandler> handler);
    
    // 调试信息加载
    void load_debug_info(const std::string& filename, std::shared_ptr<DebugInfo> info);
    
    /**
     * @brief 检查指定位置是否应该触发断点
     * @param filename 源文件名
     * @param line 行号
     * @return 是否应该触发断点
     */
    bool should_break_at(const std::string& filename, size_t line) const;

private:
    VM& vm_;
    bool debugging_;
    std::unique_ptr<DebugEventHandler> handler_;
    
    // 断点集合：文件名 -> 行号集合
    std::unordered_map<std::string, std::unordered_set<size_t>> breakpoints_;
    
    // 调试信息：函数名 -> 调试信息
    std::unordered_map<std::string, std::shared_ptr<DebugInfo>> debug_info_;
    
    // 单步执行状态
    enum class StepMode {
        NONE,
        INTO,
        OVER,
        OUT
    } step_mode_;
    size_t step_target_frame_;
    
    // 内部方法
    void handle_breakpoint(const std::string& filename, size_t line);
    void notify_event(DebugEvent event, size_t line, const std::string& message = "");
};

} // namespace viml

#endif // VIML_DEBUGGER_H